package biz

import (
	"context"
	"strings"
	"time"

	"lianzi_gos/internal/mods/mpweixin/dal"
	"lianzi_gos/internal/mods/mpweixin/schema"
	"lianzi_gos/pkg/errors"
	"lianzi_gos/pkg/util"
)

// 商品表
type Goods struct {
	Trans        *util.Trans
	GoodsDAL     *dal.Goods
	GoodsAttrDAL *dal.GoodsAttr
	StaffDAL     *dal.Staff
	CollectDal   *dal.Collect
}

// Query goods from the data access object based on the provided parameters and options.
func (a *Goods) Query(ctx context.Context, params schema.GoodsQueryParam) (*schema.GoodsQueryResult, error) {
	params.Pagination = true
	params.UID = util.FromUserID(ctx)
	result, err := a.GoodsDAL.Query(ctx, params, schema.GoodsQueryOptions{
		QueryOptions: util.QueryOptions{
			OrderFields: []util.OrderByParam{
				{Field: "g.created_at", Direction: util.DESC},
			},
		},
	})

	for _, item := range result.Data {
		item.Image = strings.Split(item.Image, ",")[0]
	}

	if err != nil {
		return nil, err
	}
	return result, nil
} // Query goods from the data access object based on the provided parameters and options.
func (a *Goods) QueryAdmin(ctx context.Context, params schema.GoodsQueryParam) (*schema.GoodsQueryResultAdmin, error) {
	params.Pagination = true
	result, err := a.GoodsDAL.QueryAdmin(ctx, params, schema.GoodsQueryOptions{
		QueryOptions: util.QueryOptions{
			OrderFields: []util.OrderByParam{
				{Field: "g.created_at", Direction: util.DESC},
			},
		},
	})

	for _, item := range result.Data {
		res := a.GoodsAttrDAL.QueryAdmin(ctx, item.ID)
		item.Children = res
	}

	if err != nil {
		return nil, err
	}
	return result, nil
}

// Get the specified goods from the data access object.
func (a *Goods) Get(ctx context.Context, id string) (*schema.Goods, error) {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return nil, err
	} else if goods == nil {
		return nil, errors.NotFound("", "Goods not found")
	}
	return goods, nil
}

// Get the specified goods from the data access object.
func (a *Goods) GetDetail(ctx context.Context, id string) (*schema.GoodsDetail, error) {
	uid := util.FromUserID(ctx)

	goods, err := a.GoodsDAL.GetDetail(ctx, id)

	if uid != "" {
		ok, err := a.CollectDal.ExistsCollect(ctx, id, uid)
		if err != nil {
			goods.IsCollect = false
		} else {
			goods.IsCollect = ok
		}
	}

	//res := a.GoodsAttrDAL.QueryAdmin(ctx, goods.ID)
	//goods.Children = res

	if err != nil {
		return nil, err
	} else if goods == nil {
		return nil, errors.NotFound("", "Goods not found")
	}
	return goods, nil
}

// Get the specified goods from the data access object. 归属人详情
func (a *Goods) GetGoodsBelongingDetail(ctx context.Context, id string) (*schema.GoodsBelongingDetail, error) {
	uid := util.FromUserID(ctx)

	goods, err := a.GoodsDAL.GetBelongingDetail(ctx, id)

	if uid != "" {
		ok, err := a.CollectDal.ExistsCollect(ctx, id, uid)
		if err != nil {
			goods.IsCollect = false
		} else {
			goods.IsCollect = ok
		}
	}

	res := a.GoodsAttrDAL.QueryAdmin(ctx, goods.ID)
	goods.Children = res

	if err != nil {
		return nil, err
	} else if goods == nil {
		return nil, errors.NotFound("", "Goods not found")
	}
	return goods, nil
}

// Create a new goods in the data access object.
func (a *Goods) Create(ctx context.Context, formItem *schema.GoodsForm) (*schema.Goods, error) {
	goods := &schema.Goods{
		ID:        util.NewXID(),
		CreatedAt: time.Now(),
		Speed:     1, // 发布
	}

	if err := formItem.FillTo(goods); err != nil {
		return nil, err
	}

	userID := util.FromUserID(ctx)
	goods.UID = userID
	staff, _ := a.StaffDAL.ExistsStaff(ctx, userID)

	/**
	*  针对单套处理
	* 单套 就是把多条数据 拼凑成一条数据 循环插入
	 * 获取的 发布的地址信息 加每个商品ID
	*/
	//var goodData schema.Goods

	obj := schema.Goods{
		ID:         util.NewXID(),
		CreatedAt:  time.Now(),
		Speed:      1, // 发布状态
		Username:   goods.Username,
		Phone:      goods.Phone,
		Code:       goods.Code,
		Types:      goods.Types,
		Address:    goods.Address,
		City:       goods.City,
		CityId:     goods.CityId,
		Province:   goods.Province,
		ProvinceId: goods.ProvinceId,
		Status:     goods.Status,
		DistrictId: goods.DistrictId,
		District:   goods.District,
		BusID:      goods.BusID,
		TwoName:    goods.TwoName,
		TwoImage:   goods.TwoImage,
		UID:        goods.UID,
	}
	attrIdArr := strings.Split(goods.AttrIds, ",")

	a.GoodsAttrDAL.UpdateStatus(ctx, attrIdArr)

	if staff == true {
		obj.Speed = 2
		obj.SuccessAt = time.Now()
		obj.WID = userID
	}

	err := a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.Create(ctx, &obj); err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, err
	}
	return goods, nil
}

// Update the specified goods in the data access object.
func (a *Goods) Update(ctx context.Context, id string, formItem *schema.GoodsForm) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}

	if err := formItem.FillTo(goods); err != nil {
		return err
	}
	goods.UpdatedAt = time.Now()

	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.Update(ctx, goods); err != nil {
			return err
		}
		return nil
	})
}

// 完成订单
func (a *Goods) UpdateSuccess(ctx context.Context, id string, formItem *schema.GoodsContract) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}

	if err := formItem.FillToContract(goods); err != nil {
		return err
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {

		if err := a.GoodsDAL.UpdateSuccess(ctx, id, goods.Contract, goods.ContractDesc, goods.MName, goods.MPhone, goods.TruePrice, 3, time.Now()); err != nil {
			return err
		}
		return nil
	})
}

// 完成订单
func (a *Goods) UpdateTwoSuccess(ctx context.Context, id string, formItem *schema.GoodsTwoForm) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}

	if err := formItem.FillToTwoSuccess(goods); err != nil {
		return err
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {

		if err := a.GoodsDAL.UpdateTwoSuccess(ctx, id, goods); err != nil {
			return err
		}
		return nil
	})
}

// 指派订单
func (a *Goods) UpdateApproved(ctx context.Context, id string, formItem *schema.GoodsZhipai) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}
	if err := formItem.FillToApproved(goods); err != nil {
		return err
	}
	zhiPaiID := util.FromUserID(ctx)
	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdateApproved(ctx, id, zhiPaiID, goods.WID, 2, time.Now()); err != nil {
			return err
		}
		return nil
	})
}

// 发布订单
func (a *Goods) UpdatePublish(ctx context.Context, id string) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdatePublish(ctx, id, 3, time.Now()); err != nil {
			return err
		}
		return nil
	})
}

// 精选
func (a *Goods) UpdateSelection(ctx context.Context, id string, formItem *schema.GoodsSelection) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}
	if err := formItem.FillToSelection(goods); err != nil {
		return err
	}
	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdateSelection(ctx, id, goods.Selection); err != nil {
			return err
		}
		return nil
	})
}

// 推荐
func (a *Goods) UpdateRecommend(ctx context.Context, id string, formItem *schema.GoodsRecommend) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}
	if err := formItem.FillToRecommend(goods); err != nil {
		return err
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdateRecommend(ctx, id, goods.Recommend); err != nil {
			return err
		}
		return nil
	})
}
func (a *Goods) UpdateStatus(ctx context.Context, id string, formItem *schema.GoodsStatus) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}
	if err := formItem.FillToStatus(goods); err != nil {
		return err
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdateStatus(ctx, id, goods.Status); err != nil {
			return err
		}
		return nil
	})
}

// 急售
func (a *Goods) UpdateSale(ctx context.Context, id string, formItem *schema.GoodsSale) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}
	if err := formItem.FillToSale(goods); err != nil {
		return err
	}
	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdateSale(ctx, id, goods.Sale); err != nil {
			return err
		}
		return nil
	})
}

// 驳回操作
func (a *Goods) UpdateOverrule(ctx context.Context, id string, formItem *schema.GoodsOverrule) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}

	if err := formItem.FillToOverrule(goods); err != nil {
		return err
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdateOverrule(ctx, id, goods.OverruleMsg, -1, time.Now()); err != nil {
			return err
		}
		return nil
	})
}

// 更新 估价
func (a *Goods) UpdatePrice(ctx context.Context, id string, formItem *schema.GoodsPrice) error {
	goods, err := a.GoodsDAL.Get(ctx, id)
	if err != nil {
		return err
	} else if goods == nil {
		return errors.NotFound("", "Goods not found")
	}

	if err := formItem.FillToPrice(goods); err != nil {
		return err
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.UpdatePrice(ctx, id, goods.Price); err != nil {
			return err
		}
		return nil
	})
}

// Delete the specified goods from the data access object.
func (a *Goods) Delete(ctx context.Context, id string) error {
	exists, err := a.GoodsDAL.Exists(ctx, id)
	if err != nil {
		return err
	} else if !exists {
		return errors.NotFound("", "Goods not found")
	}

	return a.Trans.Exec(ctx, func(ctx context.Context) error {
		if err := a.GoodsDAL.Delete(ctx, id); err != nil {
			return err
		}
		return nil
	})
}
